package com.glc.hms.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import com.glc.hms.core.compress.serializer.SnappyRedisSerializer;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@Slf4j
public class JedisConfig {
    public static final String REDIS_PREFIX = "spring.redis.cache";


    private JedisConnectionFactory redisConnectionFactory = null;
    public static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer();
    public static final GenericFastJsonRedisSerializer FAST_JSON_SERIALIZER = new GenericFastJsonRedisSerializer();
    public static final SnappyRedisSerializer SNAPPY_REDIS_SERIALIZER = new SnappyRedisSerializer(FAST_JSON_SERIALIZER);



    @Primary
    @Bean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate( RedisConnectionFactory connectionFactory) {
        return getRedisTemplate(JedisConfig.FAST_JSON_SERIALIZER,connectionFactory);
    }

    @Bean(name = "snappyRedisTemplate")
    public RedisTemplate<String, Object> snappyRedisTemplate( RedisConnectionFactory connectionFactory) {
        return getRedisTemplate(JedisConfig.SNAPPY_REDIS_SERIALIZER,connectionFactory);
    }

    private RedisTemplate<String, Object> getRedisTemplate(RedisSerializer valueSerializer, RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // set key serializer
        StringRedisSerializer keySerializer = STRING_SERIALIZER;
        // 设置key序列化类，否则key前面会多了一些乱码
        template.setKeySerializer(keySerializer);
        template.setHashKeySerializer(keySerializer);
        // set value serializer
        template.setValueSerializer(valueSerializer);
        template.setHashValueSerializer(valueSerializer);
        // 如果 KeySerializer 或者 ValueSerializer 没有配置，则对应的 KeySerializer、ValueSerializer 才使用这个 Serializer
        template.setDefaultSerializer(valueSerializer);

        template.setEnableTransactionSupport(false);

        // factory

        template.setConnectionFactory(connectionFactory);

        template.afterPropertiesSet();
        return template;
    }

    /**
     * 如果 @Cacheable、@CachePut、@CacheEvict 等注解没有配置 key，则使用这个自定义 key 生成器
     * <pre>
     *     但自定义了缓存的 key 时，难以保证 key 的唯一性，此时最好指定方法名，比如：@Cacheable(value="", key="{#root.methodName, #id}")
     * </pre>
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return (o, method, objects) -> {
            StringBuilder sb = new StringBuilder(32);
            sb.append(o.getClass().getSimpleName());
            sb.append(".");
            sb.append(method.getName());
            if (objects.length > 0) {
                sb.append("#");
            }
            String sp = "";
            for (Object object : objects) {
                sb.append(sp);
                if (object == null) {
                    sb.append("NULL");
                } else {
                    sb.append(object.toString());
                }
                sp = ".";
            }
            return sb.toString();
        };
    }

}
